<?php
/**
 * This file is part of easycrm, created by PhpStorm.
 * Author: LouXin
 * Date: 2015/1/8 14:21
 * File: SystemStatisticModel.php
 */

namespace Icsoc\CustomReportBundle\Model;

use Elasticsearch\Client;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Class SystemStatisticModel
 * @package Icsoc\CustomReportBundle\Model
 */
class SystemStatisticModel
{
    /** X秒接通量或放弃量指标 */
    const INBOUND_CONN_IN_X_SECS = 'inboundConnInXSecsNum';
    const INBOUND_ABANDON_IN_X_SECS = 'inboundAbandonInXSecsNum';

    /** 有效通话量指标名称 */
    const VALID_CONN_TOTAL_NUM = 'validConnTotalNum';
    const INBOUND_VALID_CONN_TOTAL_NUM = 'inboundValidConnTotalNum';
    const OUTBOUND_VALID_CONN_TOTAL_NUM = 'outboundValidConnTotalNum';

    /** @var array 需要计算有效通话量的指标 */
    private $validItems = array(
        self::VALID_CONN_TOTAL_NUM,
        self::INBOUND_VALID_CONN_TOTAL_NUM,
        self::OUTBOUND_VALID_CONN_TOTAL_NUM,
    );

    /** @var array 需要计算范围查找的指标 */
    private $rangeItems = array(
        self::INBOUND_ABANDON_IN_X_SECS,
        self::INBOUND_CONN_IN_X_SECS,
    );

    /** @var ContainerInterface */
    private $container;

    /** @var Client */
    private $client;

    /** @var array 总IVR呼入量 */
    private $ivrInboundTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 1)),
                    array('term' => array('log_type' => 'amount')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
            ),
        ),
    );

    /** @var array 总人工呼入量 */
    private $inboundTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 2)),
                    array('term' => array('log_type' => 'amount')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
            ),
        ),
    );

    /** @var array 呼入数据的统计，包括呼入接通量，呼入通话总时长，呼入通话平均时长 */
    private $inboundConnNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('term' => array('ext_type' => 1)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'inboundConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'inboundConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 外呼通话量 */
    private $outboundTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 9)),
                    array('term' => array('log_type' => 'amount')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
            ),
        ),
    );

    /** @var array 外呼接通量、外呼接通总时长、外呼接通平均时长 */
    private $outboundConnNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('term' => array('ext_type' => 2)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'outboundConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'outboundConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 有效通话量，有效通话总时长，有效通话平均时长 */
    private $validConnTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('range' => array('ext_type' => array('from' => 1, 'to' => 2))),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'validConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'validConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 呼入有效通话量，有效通话总时长，有效通话平均时长 */
    private $inboundValidConnTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('term' => array('ext_type' => 1)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'inboundValidConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'inboundValidConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 呼出有效通话量，有效通话总时长，有效通话平均时长 */
    private $outboundValidConnTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 4)),
                    array('term' => array('ext_type' => 2)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'outboundValidConnTotalSecs' => array('sum' => array('field' => 'secs')),
                    'outboundValidConnAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array X秒内接通量 */
    private $inboundConnInXSecsNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 12)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
            ),
        ),
    );

    /** @var array 总放弃通话量，总放弃时长、平均放弃时长 */
    private $inboundAbandonTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 3)),
                    array('term' => array('log_type' => 'amount')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'inboundAbandonTotalSecs' => array('sum' => array('field' => 'secs')),
                    'inboundAbandonAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array X秒放弃量 */
    private $inboundAbandonInXSecsNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 3)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
            ),
        ),
    );

    /** @var array 总排队次数，排队总时长，排队平均时长 */
    private $queueTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 1)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'queueTotalSecs' => array('sum' => array('field' => 'secs')),
                    'queueAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 接通通话的排队总次数，接通通话的排队总时长，接通通话的平均排队时长 */
    private $connQueueTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 12)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'connQueueTotalSecs' => array('sum' => array('field' => 'secs')),
                    'connQueueAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 内线通话量，内线通话总时长，内线通话平均时长 */
    private $ringTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 2)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'ringTotalSecs' => array('sum' => array('field' => 'secs')),
                    'ringAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 事后处理量，事后处理总时长，事后处理平均时长 */
    private $waitTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 9)),
                    array('term' => array('ext_type' => 1)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'waitTotalSecs' => array('sum' => array('field' => 'secs')),
                    'waitAvgSecs' => array('avg' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 登录次数、登录总时长 */
    private $loginTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 8)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'loginTotalSecs' => array('sum' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 就绪总时长 */
    private $readyTotalSecs = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 10)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'readyTotalSecs' => array('sum' => array('field' => 'secs')),
                ),
            ),
        ),
    );

    /** @var array 示忙总时长 */
    private $busyTotalNum = array(
        'filter' => array(
            'bool' => array(
                'must' => array(
                    array('term' => array('type' => 11)),
                    array('term' => array('log_type' => 'time')),
                ),
            ),
        ),
        'aggs' => array(
            'vcc_groups' => array(
                'terms' => array('field' => 'vcc_id', 'size' => 0),
                'aggs' => array(
                    'ext_busy' => array(
                        'terms' => array('field' => 'ext_option', 'size' => 0),
                        'aggs' => array(
                            'busyTotalSecs' => array('sum' => array('field' => 'secs')),
                            'busyAvgSecs' => array('avg' => array('field' => 'secs')),
                        ),
                    ),
                ),
            ),
        ),
    );

    /** @var array 所有的统计指标 */
    private $statisticItems = array();

    /** @var array 所有需要计算的指标 */
    private $calculateItems = array();

    /**
     * SystemStatisticModel constructor.
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $hosts = $this->container->getParameter('elasticsearch_hosts');
        $this->client = new Client(array(
            'hosts' => $hosts,
            'logging' => false,
        ));

        /** 如果没有设置置忙原因不按置忙原因查询 */
        $user = $this->container->get("security.token_storage")->getToken()->getUser();
        $vccId = $user->getVccId();

        $conn = $this->container->get('doctrine.dbal.default_connection');
        $reasons = $conn->fetchAll(
            'SELECT id,stat_reason FROM win_agstat_reason WHERE vcc_id=:vcc_id',
            array(':vcc_id' => $vccId)
        );

        if (empty($reasons)) {
            /** @var array 示忙总时长 */
            $this->busyTotalNum = array(
                'filter' => array(
                    'bool' => array(
                        'must' => array(
                            array('term' => array('type' => 11)),
                            array('term' => array('log_type' => 'time')),
                        ),
                    ),
                ),
                'aggs' => array(
                    'vcc_groups' => array(
                        'terms' => array('field' => 'vcc_id', 'size' => 0),
                        'aggs' => array(
                            'busyTotalSecs' => array('sum' => array('field' => 'secs')),
                            'busyAvgSecs' => array('avg' => array('field' => 'secs')),
                        ),
                    ),
                ),
            );
        }

        //所有需要统计的项
        $this->statisticItems = array(
            'ivrInboundTotalNum' => $this->ivrInboundTotalNum,
            'inboundTotalNum' => $this->inboundTotalNum,
            'inboundConnNum' => $this->inboundConnNum,
            'inboundConnInXSecsNum' => $this->inboundConnInXSecsNum,
            'inboundValidConnTotalNum' => $this->inboundValidConnTotalNum,
            'inboundAbandonTotalNum' => $this->inboundAbandonTotalNum,
            'inboundAbandonInXSecsNum' => $this->inboundAbandonInXSecsNum,
            'queueTotalNum' => $this->queueTotalNum,
            'connQueueTotalNum' => $this->connQueueTotalNum,
            'ringTotalNum' => $this->ringTotalNum,
            'waitTotalNum' => $this->waitTotalNum,
            'outboundTotalNum' => $this->outboundTotalNum,
            'outboundConnNum' => $this->outboundConnNum,
            'validConnTotalNum' => $this->validConnTotalNum,
            'outboundValidConnTotalNum' => $this->outboundValidConnTotalNum,
            'loginTotalNum' => $this->loginTotalNum,
            'readyTotalSecs' => $this->readyTotalSecs,
            'busyTotalNum' => $this->busyTotalNum,
        );

        //所有需要计算的项
        /*$calculateItems = $this->getcalculateItemAction();
        if (!empty($calculateItems)) {
            $this->calculateItems = array();
            foreach ($calculateItems['system'] as $key => $val) {
                $val['denominator'] = isset($val['denominator']) ? $val['denominator'] : array();
                $this->calculateItems[$key] = array(
                    'numerator' => array($val['numerator']),
                    'denominator' => array($val['denominator']),
                );
            }
        } else {
            $this->calculateItems = array(
                'inboundRate' => array(
                    'numerator' => array('inboundTotalNum'),
                    'denominator' => array('ivrInboundTotalNum'),
                ),
                'inboundConnRate' => array(
                    'numerator' => array('inboundConnNum'),
                    'denominator' => array('inboundTotalNum'),
                ),
                'inboundAbandonRate' => array(
                    'numerator' => array('inboundAbandonTotalNum'),
                    'denominator' => array('inboundTotalNum'),
                ),
                'outboundConnRate' => array(
                    'numerator' => array('outboundConnNum'),
                    'denominator' => array('outboundTotalNum'),
                ),
                'inboundConnInXSecsRate' => array(
                    'numerator' => array('inboundConnInXSecsNum'),
                    'denominator' => array('inboundConnNum'),
                ),
                'inboundAbandonInXSecsRate' => array(
                    'numerator' => array('inboundAbandonInXSecsNum'),
                    'denominator' => array('inboundConnNum'),
                ),
                'workRate' => array(
                    'numerator' => array('inboundConnTotalSecs', 'outboundConnTotalSecs', 'waitTotalSecs'),
                    'denominator' => array('loginTotalSecs'),
                ),
            );
        }*/
    }

    /**
     * 获取技能组天报表统计数据
     *
     * @param array $param 参数，格式为
     *                     array(
     *                         items = array(//统计的字段项
     *                             inboundConnNum,
     *                             inboundConnTotalSecs,
     *                             ...,
     *                         ),
     *                         query = array(//查询条件
     *                             vcc_id => 1,//企业id（必需）
     *                             start_time => 1,//开始时间（必需）
     *                             end_time => 1,//结束时间（必需）
     *                             ag_id => 1,//坐席id，多个坐席id逗号分隔
     *                             que_id => 1,//技能组id，多个技能组id逗号分隔
     *                             group_id => 1,//业务组id，多个业务组id逗号分隔
     *                         )
     *                         options = array(//其他选项
     *                             validSecs => 60,//有效通话时长
     *                             inboundConnInXSecsNum => array(15,20,25,30),//X秒内接通量
     *                             inboundAbandonlNumInXSecs => array(15,20,25,30),//X秒内放弃量
     *                         )
     *                     )
     *
     * @return array
     */
    public function getSystemDayStatisticData(array $param)
    {
        if (empty($param)) {
            return array(
                'code' => 401,
                'message' => '统计参数为空',
            );
        }

        if (!is_array($param)) {
            return array(
                'code' => 402,
                'message' => '统计参数格式不为数组',
            );
        }

        if (empty($param['items'])) {
            return array(
                'code' => 403,
                'message' => '统计参数中的字段项items为空',
            );
        }

        if (empty($param['query']['vcc_id'])) {
            return array(
                'code' => 404,
                'message' => '统计参数中的查询项query中缺少企业ID',
            );
        }

        if (empty($param['query']['start_time'])) {
            return array(
                'code' => 405,
                'message' => '统计参数中的查询项query中缺少开始时间start_time',
            );
        }

        if (empty($param['query']['end_time'])) {
            return array(
                'code' => 406,
                'message' => '统计参数中的查询项query中缺少结束时间end_time',
            );
        }

        // 默认计算项
        $this->calculateItems = array(
            'inboundRate' => array(
                'numerator' => array('inboundTotalNum'),
                'denominator' => array('ivrInboundTotalNum'),
            ),
            'inboundConnRate' => array(
                'numerator' => array('inboundConnNum'),
                'denominator' => array('inboundTotalNum'),
            ),
            'inboundAbandonRate' => array(
                'numerator' => array('inboundAbandonTotalNum'),
                'denominator' => array('inboundTotalNum'),
            ),
            'outboundConnRate' => array(
                'numerator' => array('outboundConnNum'),
                'denominator' => array('outboundTotalNum'),
            ),
            'inboundConnInXSecsRate' => array(
                'numerator' => array('inboundConnInXSecsNum'),
                'denominator' => array('inboundConnNum'),
            ),
            'inboundAbandonInXSecsRate' => array(
                'numerator' => array('inboundAbandonInXSecsNum'),
                'denominator' => array('inboundConnNum'),
            ),
            'workRate' => array(
                'numerator' => array('inboundConnTotalSecs', 'outboundConnTotalSecs', 'waitTotalSecs'),
                'denominator' => array('loginTotalSecs'),
            ),
        );

        /** @var array $calculateItems 获取自定义配置的计算项 */
        $roleId = empty($param['role_id']) ? 0 : $param['role_id'];
        $calculateItems = $this->container->get('icsoc_data.model.role')->getcalculateItem($roleId);
        if (empty($calculateItems['system'])) {
            $calculateItems = array();
        } else {
            $calculateItems = $this->container->get('icsoc_report_for_role.model.report')->filterCalculateItems($calculateItems['system']);
        }

        if (!empty($calculateItems)) {
            foreach ($calculateItems as $key => $val) {
                $val['denominator'] = isset($val['denominator']) ? $val['denominator'] : array();
                $this->calculateItems[$key] = array(
                    'numerator' => array($val['numerator']),
                    'denominator' => array($val['denominator']),
                );
            }
        }

        //处理查询条件
        $query = array();
        $vccId = empty($param['query']['vcc_id']) ? 0 : $param['query']['vcc_id'];
        $query[] = array('match' => array('vcc_id' => $vccId));

        $startTime = empty($param['query']['start_time']) ? 0 : $param['query']['start_time'];
        $endTime = empty($param['query']['end_time']) ? 0 : $param['query']['end_time'];
        $query[] = array(
            'range' => array(
                'call_time' => array(
                    'gte' => $startTime,
                    'lte' => $endTime,
                ),
            ),
        );

        $agIds = empty($param['query']['ag_id']) ? 0 : $param['query']['ag_id'];
        if (!empty($agIds)) {
            $agIdArray = explode(',', $agIds);
            $query[] = array(
                'terms' => array(
                    'ag_id' => $agIdArray,
                ),
            );
        }

        $queIds = empty($param['query']['que_id']) ? 0 : $param['query']['que_id'];
        if (!empty($queIds)) {
            $queIdArray = explode(',', $queIds);
            $query[] = array(
                'terms' => array(
                    'que_id' => $queIdArray,
                ),
            );
        }

        $groupIds = empty($param['query']['group_id']) ? 0 : $param['query']['group_id'];
        if (!empty($groupIds)) {
            $groupIdArray = explode(',', $groupIds);
            $query[] = array(
                'terms' => array(
                    'group_id' => $groupIdArray,
                ),
            );
        }

        // ivr进线量中过滤中继号码
        $phones = empty($param['query']['phones']) ? '' : $param['query']['phones'];
        if (!empty($phones)) {
            $phonesArray = explode(',', $phones);
            array_push(
                $this->statisticItems['ivrInboundTotalNum']['filter']['bool']['must'],
                array(
                    'terms' => array(
                        'ext_option' => $phonesArray,
                    ),
                )
            );
        }

        //处理统计字段项
        $aggsItems = array();
        $items = empty($param['items']) ? array() : $param['items'];
        foreach ($items as $item) {
            if (isset($this->statisticItems[$item])) {
                $aggsItems[$item] = $this->statisticItems[$item];

                //处理有效通话量指标
                if (in_array($item, $this->validItems)) {
                    if (isset($param['options']['validSecs'])) {
                        array_push(
                            $aggsItems[$item]['filter']['bool']['must'],
                            array('range' => array('secs' => array('gte' => $param['options']['validSecs'])))
                        );
                    }
                }

                //处理X秒内接通或放弃量指标
                if (in_array($item, $this->rangeItems)) {
                    if (!empty($param['options'][$item]) && is_array($param['options'][$item])) {
                        $rangeFilter = array();
                        //处理ranges指标
                        foreach ($param['options'][$item] as $rangeValue) {
                            /**
                             * 由于to统计为<该值，但我们需要的是<=，所以我们给该值+0.0001
                             */
                            $rangeFilter[] = array('to' => $rangeValue + 0.0001);
                        }

                        $aggsItems[$item]['aggs']['vcc_groups']['aggs'] = array(
                            'ext_in_secs' => array(
                                'range' => array(
                                    'field' => 'secs',
                                    'ranges' => $rangeFilter,
                                ),
                            ),
                        );
                    }
                }
            }
        }

        //获取统计结果
        $params = array(
            'index' => $this->container->getParameter('elasticsearch_index_name'),
            'type' => 'tmp_logs',
            'search_type' => 'count',
            'body' => array(
                'query' => array(
                    'bool' => array(
                        'must' => $query,
                    ),
                ),
                'aggs' => array(
                    //按日期统计所有技能组的统计数据
                    'agg_date' => array(
                        'terms' => array(
                            'field' => 'day',
                            'format' => 'yyyy-MM-dd',
                            'size' => 0,
                        ),
                        'aggs' => $aggsItems,
                    ),
                ),
            ),
        );
        $result = $this->client->search($params);
        $took = empty($result['took']) ? 0 : $result['took'];

        /**
         * 解析统计返回的结果，原始数据结构见例子../Resources/doc/SystemDaySample.json
         * 解析完成后的数据结构见例子../Resources/doc/SystemDayResult.json
         */
        $buckets = empty($result['aggregations']['agg_date']['buckets']) ?
            array() : $result['aggregations']['agg_date']['buckets'];

        //释放result占用的内存，防止超过内存限制
        unset($result);

        $parsedResult = array('took' => $took, 'data' => array());
        //记录无法从搜索结果中获取的指标，初始化为所有的指标，获取一项删除一项
        $itemsCanNotGetFromResult = $items;

        /**
         * $buckets为按日期统计的结果，遍历处理各个日期的数据
         */
        foreach ($buckets as $bucket) {
            $statisticDate = empty($bucket['key_as_string']) ? 0 : $bucket['key_as_string'];
            unset($bucket['key']);
            unset($bucket['key_as_string']);
            unset($bucket['doc_count']);

            //初始化所有坐席的所有统计数据指标为0
            foreach ($items as $item) {
                $parsedResult['data'][$statisticDate][$vccId][$item] = 0;
            }

            /**
             * $bucket为按指标统计的结果，遍历处理各个指标的数据
             */
            foreach ($bucket as $bucketItem => $bucketData) {
                $subBuckets = empty($bucketData['vcc_groups']['buckets']) ?
                    array() : $bucketData['vcc_groups']['buckets'];

                //将可以从搜索结果中获取的指标从“$itemsCanNotGetFromResult”删除
                if (($searchKey = array_search($bucketItem, $itemsCanNotGetFromResult)) !== false) {
                    unset($itemsCanNotGetFromResult[$searchKey]);
                }

                /**
                 * $subBuckets为按企业统计的数据，遍历处理各个企业的统计数据
                 */
                foreach ($subBuckets as $subBucketData) {
                    $vccid = empty($subBucketData['key']) ? 0 : $subBucketData['key'];
                    $docCount = empty($subBucketData['doc_count']) ? 0 : $subBucketData['doc_count'];
                    $parsedResult['data'][$statisticDate][$vccid][$bucketItem] = $docCount;
                    unset($subBucketData['key']);
                    unset($subBucketData['doc_count']);

                    /**
                     * 处理各个指标下的相关指标的统计数据
                     * 例如呼入接通量相关的统计数据为总呼入接通通话时长、平均呼入接通通话时长
                     *
                     * @var string $subBucketDataItem 相关指标
                     * @var array $subBucketDataData 相关指标的值，格式为包含键value的数组或包含子统计的数组
                     */
                    foreach ($subBucketData as $subBucketDataItem => $subBucketDataData) {
                        //将可以从搜索结果中获取的指标从“$itemsCanNotGetFromResult”删除
                        if (($searchKey = array_search($bucketItem, $itemsCanNotGetFromResult)) !== false) {
                            unset($itemsCanNotGetFromResult[$searchKey]);
                        }

                        if (in_array($subBucketDataItem, $items)) {
                            /**
                             * 该项为需要统计的项，不包含子统计的数据
                             */
                            $parsedResult['data'][$statisticDate][$vccid][$subBucketDataItem] =
                                empty($subBucketDataData['value']) ? 0 : $subBucketDataData['value'];
                        } else {
                            /**
                             * 该项为不需要统计的项，判断是否包含子统计数据，包含则继续处理子统计
                             *
                             * 需要统计的项为：示忙原因统计、X秒接通量统计、X秒放弃量统计
                             * 示忙原因统计：根据ext_option使用terms统计每个类别的数量，分类统计的键值根据key字段类命名
                             * X秒接通量统计：根据secs使用range统计各个范围的数量，range统计的各个范围的键值根据to字段来命名
                             * X秒放弃量统计：根据secs使用range统计各个范围的数量，range统计的各个范围的键值根据to字段来命名
                             *
                             * 处理方式为将统计的结果存在在键值为该指标名称的数组下，例如
                             * "inboundConnInXSecsNum": {
                             *   "15": 1356,
                             *   "20": 1384,
                             *   "25": 1419,
                             *   "30": 1441,
                             *   "45": 1484
                             *   },
                             *   "inboundConnInXSecsRate": {
                             *   "15": "85.77%",
                             *   "20": "87.54%",
                             *   "25": "89.75%",
                             *   "30": "91.14%",
                             *   "45": "93.86%"
                             *   }
                             */
                            if (isset($subBucketDataData['buckets'])) {
                                $childBuckets = empty($subBucketDataData['buckets']) ?
                                    array() : $subBucketDataData['buckets'];
                                $parsedResult['data'][$statisticDate][$vccid][$bucketItem] = array();

                                /**
                                 * 继续处理子统计中的项【包括X秒接通量、X秒放弃量、示忙原因统计】
                                 */
                                foreach ($childBuckets as $childBucket) {
                                    if (isset($childBucket['to'])) {
                                        //将15.0001等转为整数15，用于统计range统计，此统计没有相关指标的统计，例如相关的时长
                                        $childKey = !empty($childBucket['to']) || $childBucket['to'] == 0 ?
                                            intval($childBucket['to']) : "0";
                                        $count = empty($childBucket['doc_count']) ? 0 : $childBucket['doc_count'];
                                        $parsedResult['data'][$statisticDate][$vccid][$bucketItem][$childKey] = $count;
                                    } else {
                                        //用于统计子项中的terms统计，例如统计具体示忙原因的ext_option字段的统计
                                        $childKey = !empty($childBucket['key']) || $childBucket['key'] == 0 ?
                                            strval($childBucket['key']) : "0";
                                        $count = empty($childBucket['doc_count']) ? 0 : $childBucket['doc_count'];
                                        $parsedResult['data'][$statisticDate][$vccid][$bucketItem][$childKey] = $count;

                                        unset($childBucket['key']);
                                        unset($childBucket['doc_count']);
                                        /**
                                         * 处理子统计中的相关指标
                                         */
                                        foreach ($childBucket as $cbk => $childBucketData) {
                                            if (!isset($parsedResult['data'][$statisticDate][$vccid][$cbk])) {
                                                $parsedResult['data'][$statisticDate][$vccid][$cbk] = array();
                                            }
                                            if (!is_array($parsedResult['data'][$statisticDate][$vccid][$cbk])) {
                                                $parsedResult['data'][$statisticDate][$vccid][$cbk] = array();
                                            }
                                            $parsedResult['data'][$statisticDate][$vccid][$cbk][$childKey] =
                                                empty($childBucketData['value']) ? 0 : $childBucketData['value'];
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        //处理需要计算的项，按日期分组
        foreach ($parsedResult['data'] as $dateStatistic => $dateStatisticData) {
            //遍历处理技能组、坐席或企业的数据，按技能组、坐席或企业分组
            foreach ($dateStatisticData as $queStatistic => $queStatisticData) {
                //遍历处理各个指标的数据，按指标分组

                foreach ($queStatisticData as $item => $itemData) {
                    //如果是搜索结果中未统计的项并且是需要计算的项，则执行计算

                    if (in_array($item, $itemsCanNotGetFromResult) && isset($this->calculateItems[$item])) {
                        $calculateRules = empty($this->calculateItems[$item]) ? array() : $this->calculateItems[$item];

                        //未设置计算规则
                        if (empty($calculateRules)) {
                            continue;
                        }

                        $calculItemConfig = $calculateItems;
                        $numerator = empty($calculateRules['numerator']) ? array() : $calculateRules['numerator'];
                        $denominator = empty($calculateRules['denominator']) ? array() : $calculateRules['denominator'];
                        $numeratorValue = 0;
                        $denominatorValue = 0;

                        //计算分母的值
                        foreach ($denominator as $ruleItem) {
                            if (is_array($ruleItem)) {
                                foreach ($ruleItem as $key => $rules) {
                                    if ($key == 'multiply') {//先处理乘法运算
                                        if (empty($rules['plus'] && empty($rules['minus']))) {
                                            continue;
                                        }
                                        $denominatorValue += $this->processMultiplyItems($rules, $queStatisticData, $parsedResult['data'][$dateStatistic][$queStatistic], array_keys($calculItemConfig));
                                    } else {
                                        foreach ($rules as $rule) {
                                            if (empty($rule)) {
                                                continue;
                                            }
                                            if (!isset($queStatisticData[$rule])) {
                                                if (is_numeric($rule)) {
                                                    $queStatisticData[$rule] = (int) $rule;
                                                    $parsedResult['data'][$dateStatistic][$queStatistic][$rule] = (int) $rule;
                                                } else {
                                                    $queStatisticData[$rule] = 0;
                                                }
                                            }
                                            if (is_array($queStatisticData[$rule])) {
                                                foreach ($queStatisticData[$rule] as $val) {
                                                    $denominatorValue += $val;
                                                }
                                            } else {
                                                $calculItems = array();
                                                $calculItemConfig = isset($calculateItems['system']) ? $calculateItems['system'] : array();

                                                foreach ($calculItemConfig as $calculItemK => $calculItemV) {
                                                    $calculItems[] = $calculItemK;
                                                }

                                                if (in_array($rule, $calculItems)) {
                                                    if ($key == 'plus') {
                                                        $denominatorValue += isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                    } else {
                                                        $denominatorValue -= isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                    }
                                                } else {
                                                    if ($key == 'plus') {
                                                        $denominatorValue += $queStatisticData[$rule];
                                                    } else {
                                                        $denominatorValue -= $queStatisticData[$rule];
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            } else {
                                if (is_numeric($ruleItem)) {
                                    $queStatisticData[$ruleItem] = (int) $ruleItem;
                                }
                                $denominatorValue += $queStatisticData[$ruleItem];
                            }
                        }

                        //计算分子的值
                        foreach ($numerator as $ruleItem) {
                            if (is_array($ruleItem)) {
                                foreach ($ruleItem as $key => $rules) {
                                    if ($key == 'multiply') {
                                        if (empty($rules['plus'] && empty($rules['minus']))) {
                                            continue;
                                        }
                                        $numeratorValue += $this->processMultiplyItems($rules, $queStatisticData, $parsedResult['data'][$dateStatistic][$queStatistic], array_keys($calculItemConfig));
                                    } else {
                                        foreach ($rules as $rule) {
                                            if (empty($rule)) {
                                                continue;
                                            }
                                            if (!isset($queStatisticData[$rule]) || empty($queStatisticData[$rule])) {
                                                if (is_numeric($rule)) {
                                                    $queStatisticData[$rule] = (int) $rule;
                                                    $parsedResult['data'][$dateStatistic][$queStatistic][$rule] = (int) $rule;
                                                } else {
                                                    $queStatisticData[$rule] = 0;
                                                }
                                            }

                                            if (is_array($queStatisticData[$rule])) {
                                                $ruleItemValue = isset($queStatisticData[$rule]) ? $queStatisticData[$rule] : array();
                                            } else {
                                                $ruleItemValue = isset($queStatisticData[$rule]) ? $queStatisticData[$rule] : 0;
                                            }

                                            if (is_array($ruleItemValue)) {
                                                $numeratorValue = array();
                                                //需要计算的值为一个数组，如X秒接通量、接通率
                                                foreach ($ruleItemValue as $key => $value) {
                                                    if (isset($numeratorValue[$key])) {
                                                        $numeratorValue[$key] += isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                                    } else {
                                                        $numeratorValue[$key] = isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                                    }
                                                }
                                            } else {
                                                if (is_array($queStatisticData[$rule])) {
                                                    foreach ($queStatisticData[$rule] as $val) {
                                                        $numeratorValue += $val;
                                                    }
                                                } else {
                                                    $calculItems = array();
                                                    $calculItemConfig = isset($calculateItems['system']) ? $calculateItems['system'] : array();
                                                    foreach ($calculItemConfig as $calculItemK => $calculItemV) {
                                                        $calculItems[] = $calculItemK;
                                                    }
                                                    if (in_array($rule, $calculItems)) {
                                                        if ($key == 'plus') {
                                                            $numeratorValue += isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                        } else {
                                                            $numeratorValue -= isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                        }
                                                    } else {
                                                        if ($key == 'plus') {
                                                            $numeratorValue += $queStatisticData[$rule];
                                                        } else {
                                                            $numeratorValue -= $queStatisticData[$rule];
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            } else {
                                $ruleItemValue = isset($queStatisticData[$ruleItem]) ? $queStatisticData[$ruleItem] : is_numeric($ruleItem) ? (int) $ruleItem : 0;
                                if (is_array($ruleItemValue)) {
                                    $numeratorValue = array();
                                    //需要计算的值为一个数组，如X秒接通量、接通率
                                    foreach ($ruleItemValue as $key => $value) {
                                        if (isset($numeratorValue[$key])) {
                                            $numeratorValue[$key] += isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                        } else {
                                            $numeratorValue[$key] = isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                        }
                                    }
                                } else {
                                    //需要计算的值为单个值
                                    if (is_numeric($ruleItem)) {
                                        $queStatisticData[$ruleItem] = (int) $ruleItem;
                                    }
                                    $numeratorValue += $queStatisticData[$ruleItem];
                                }
                            }
                        }

                        //计算统计项的值
                        if (isset($calculateItems[$item])) {
                            if (empty($calculateItems[$item]['percent'])) {
                                if (is_array($numeratorValue)) {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                    foreach ($numeratorValue as $key => $value) {
                                        $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                            $denominatorValue == 0 ?
                                                $numeratorValue[$key] : (round($numeratorValue[$key] / $denominatorValue, 1));
                                    }
                                } else {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                        $numeratorValue : (round($numeratorValue / $denominatorValue, 1));
                                }
                            } else {
                                if (is_array($numeratorValue)) {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                    foreach ($numeratorValue as $key => $value) {
                                        if ($denominatorValue == 0) {
                                            $resultValue = 0;
                                        } else {
                                            if (($numeratorValue[$key] / $denominatorValue) > 1) {
                                                $resultValue = 1;
                                            } else {
                                                $resultValue = ($numeratorValue[$key] / $denominatorValue);
                                            }
                                        }
                                        $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                            $denominatorValue == 0 ?
                                                '0%' : (round($resultValue, 4) * 100).'%';
                                    }
                                } else {
                                    if ($denominatorValue == 0) {
                                        $resultValue = 0;
                                    } else {
                                        if (($numeratorValue / $denominatorValue) > 1) {
                                            $resultValue = 1;
                                        } else {
                                            $resultValue = ($numeratorValue / $denominatorValue);
                                        }
                                    }
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                        '0%' : (round($resultValue, 4) * 100).'%';
                                }
                            }
                        } else {
                            if (is_array($numeratorValue)) {
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                foreach ($numeratorValue as $key => $value) {
                                    if ($denominatorValue == 0) {
                                        $resultValue = 0;
                                    } else {
                                        if (($numeratorValue[$key] / $denominatorValue) > 1) {
                                            $resultValue = 1;
                                        } else {
                                            $resultValue = ($numeratorValue[$key] / $denominatorValue);
                                        }
                                    }
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                        $denominatorValue == 0 ?
                                            '0%' : (round($resultValue, 4) * 100).'%';
                                }
                            } else {
                                if ($denominatorValue == 0) {
                                    $resultValue = 0;
                                } else {
                                    if (($numeratorValue / $denominatorValue) > 1) {
                                        $resultValue = 1;
                                    } else {
                                        $resultValue = ($numeratorValue / $denominatorValue);
                                    }
                                }
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                    '0%' : (round($resultValue, 4) * 100).'%';
                            }
                        }
                    }

                    //处理浮点数的格式
                    if (is_float($itemData)) {
                        $parsedResult['data'][$dateStatistic][$queStatistic][$item] = round($itemData, 1);
                    } elseif (is_array($itemData)) {
                        foreach ($itemData as $subItem => $data) {
                            if (is_float($data)) {
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item][$subItem] = round($data, 1);
                            }
                        }
                    }
                }
            }
        }

        return $parsedResult;
    }

    /**
     * 获取技能组月报表统计数据
     *
     * @param array $param 参数，格式为
     *                     array(
     *                         items = array(//统计的字段项
     *                             inboundConnNum,
     *                             inboundConnTotalSecs,
     *                             ...,
     *                         ),
     *                         query = array(//查询条件
     *                             vcc_id => 1,//企业id（必需）
     *                             start_time => 1,//开始时间（必需）
     *                             end_time => 1,//结束时间（必需）
     *                             ag_id => 1,//坐席id，多个坐席id逗号分隔
     *                             que_id => 1,//技能组id，多个技能组id逗号分隔
     *                             group_id => 1,//业务组id，多个业务组id逗号分隔
     *                         )
     *                         options = array(//其他选项
     *                             validSecs => 60,//有效通话时长
     *                             inboundConnInXSecsNum => array(15,20,25,30),//X秒内接通量
     *                             inboundAbandonlNumInXSecs => array(15,20,25,30),//X秒内放弃量
     *                         )
     *                     )
     *
     * @return array
     */
    public function getSystemMonthStatisticData(array $param)
    {
        if (empty($param)) {
            return array(
                'code' => 401,
                'message' => '统计参数为空',
            );
        }

        if (!is_array($param)) {
            return array(
                'code' => 402,
                'message' => '统计参数格式不为数组',
            );
        }

        if (empty($param['items'])) {
            return array(
                'code' => 403,
                'message' => '统计参数中的字段项items为空',
            );
        }

        if (empty($param['query']['vcc_id'])) {
            return array(
                'code' => 404,
                'message' => '统计参数中的查询项query中缺少企业ID',
            );
        }

        if (empty($param['query']['start_time'])) {
            return array(
                'code' => 405,
                'message' => '统计参数中的查询项query中缺少开始时间start_time',
            );
        }

        if (empty($param['query']['end_time'])) {
            return array(
                'code' => 406,
                'message' => '统计参数中的查询项query中缺少结束时间end_time',
            );
        }

        // 默认配置的计算项
        $this->calculateItems = array(
            'inboundRate' => array(
                'numerator' => array('inboundTotalNum'),
                'denominator' => array('ivrInboundTotalNum'),
            ),
            'inboundConnRate' => array(
                'numerator' => array('inboundConnNum'),
                'denominator' => array('inboundTotalNum'),
            ),
            'inboundAbandonRate' => array(
                'numerator' => array('inboundAbandonTotalNum'),
                'denominator' => array('inboundTotalNum'),
            ),
            'outboundConnRate' => array(
                'numerator' => array('outboundConnNum'),
                'denominator' => array('outboundTotalNum'),
            ),
            'inboundConnInXSecsRate' => array(
                'numerator' => array('inboundConnInXSecsNum'),
                'denominator' => array('inboundConnNum'),
            ),
            'inboundAbandonInXSecsRate' => array(
                'numerator' => array('inboundAbandonInXSecsNum'),
                'denominator' => array('inboundConnNum'),
            ),
            'workRate' => array(
                'numerator' => array('inboundConnTotalSecs', 'outboundConnTotalSecs', 'waitTotalSecs'),
                'denominator' => array('loginTotalSecs'),
            ),
        );

        /** @var array $calculateItems 获取自定义配置的计算项 */
        $roleId = empty($param['role_id']) ? 0 : $param['role_id'];
        $calculateItems = $this->container->get('icsoc_data.model.role')->getcalculateItem($roleId);

        if (!empty($calculateItems)) {
            foreach ($calculateItems['system'] as $key => $val) {
                $val['denominator'] = isset($val['denominator']) ? $val['denominator'] : array();
                $this->calculateItems[$key] = array(
                    'numerator' => array($val['numerator']),
                    'denominator' => array($val['denominator']),
                );
            }
        }

        //处理查询条件
        $query = array();
        $vccId = empty($param['query']['vcc_id']) ? 0 : $param['query']['vcc_id'];
        $query[] = array('match' => array('vcc_id' => $vccId));

        $startTime = empty($param['query']['start_time']) ? 0 : $param['query']['start_time'];
        $endTime = empty($param['query']['end_time']) ? 0 : $param['query']['end_time'];
        $query[] = array(
            'range' => array(
                'call_time' => array(
                    'gte' => $startTime,
                    'lte' => $endTime,
                ),
            ),
        );

        $agIds = empty($param['query']['ag_id']) ? 0 : $param['query']['ag_id'];
        if (!empty($agIds)) {
            $agIdArray = explode(',', $agIds);
            $query[] = array(
                'terms' => array(
                    'ag_id' => $agIdArray,
                ),
            );
        }

        $queIds = empty($param['query']['que_id']) ? 0 : $param['query']['que_id'];
        if (!empty($queIds)) {
            $queIdArray = explode(',', $queIds);
            $query[] = array(
                'terms' => array(
                    'que_id' => $queIdArray,
                ),
            );
        }

        $groupIds = empty($param['query']['group_id']) ? 0 : $param['query']['group_id'];
        if (!empty($groupIds)) {
            $groupIdArray = explode(',', $groupIds);
            $query[] = array(
                'terms' => array(
                    'group_id' => $groupIdArray,
                    'minimum_should_match' => 1,
                ),
            );
        }

        //处理统计字段项
        $aggsItems = array();
        $items = empty($param['items']) ? array() : $param['items'];
        foreach ($items as $item) {
            if (isset($this->statisticItems[$item])) {
                $aggsItems[$item] = $this->statisticItems[$item];

                //处理有效通话量指标
                if (in_array($item, $this->validItems)) {
                    if (isset($param['options']['validSecs'])) {
                        array_push(
                            $aggsItems[$item]['filter']['bool']['must'],
                            array('range' => array('secs' => array('gte' => $param['options']['validSecs'])))
                        );
                    }
                }

                //处理X秒内接通或放弃量指标
                if (in_array($item, $this->rangeItems)) {
                    if (!empty($param['options'][$item]) && is_array($param['options'][$item])) {
                        $rangeFilter = array();
                        //处理ranges指标
                        foreach ($param['options'][$item] as $rangeValue) {
                            /**
                             * 由于to统计为<该值，但我们需要的是<=，所以我们给该值+0.0001
                             */
                            $rangeFilter[] = array('to' => $rangeValue + 0.0001);
                        }

                        $aggsItems[$item]['aggs']['vcc_groups']['aggs'] = array(
                            'ext_in_secs' => array(
                                'range' => array(
                                    'field' => 'secs',
                                    'ranges' => $rangeFilter,
                                ),
                            ),
                        );
                    }
                }
            }
        }

        //获取统计结果
        $params = array(
            'index' => $this->container->getParameter('elasticsearch_index_name'),
            'type' => 'tmp_logs',
            'search_type' => 'count',
            'body' => array(
                'query' => array(
                    'bool' => array(
                        'must' => $query,
                    ),
                ),
                'aggs' => array(
                    //按日期统计所有技能组的统计数据
                    'agg_date' => array(
                        'terms' => array(
                            'field' => 'month',
                            'format' => 'yyyy-MM',
                            'size' => 0,
                        ),
                        'aggs' => $aggsItems,
                    ),
                ),
            ),
        );
        $result = $this->client->search($params);
        $took = empty($result['took']) ? 0 : $result['took'];

        /**
         * 解析统计返回的结果，原始数据结构见例子../Resources/doc/SystemDaySample.json
         * 解析完成后的数据结构见例子../Resources/doc/SystemDayResult.json
         */
        $buckets = empty($result['aggregations']['agg_date']['buckets']) ?
            array() : $result['aggregations']['agg_date']['buckets'];

        //释放result占用的内存，防止超过内存限制
        unset($result);

        $parsedResult = array('took' => $took, 'data' => array());
        //记录无法从搜索结果中获取的指标，初始化为所有的指标，获取一项删除一项
        $itemsCanNotGetFromResult = $items;

        /**
         * $buckets为按日期统计的结果，遍历处理各个日期的数据
         */
        foreach ($buckets as $bucket) {
            $statisticDate = empty($bucket['key_as_string']) ? 0 : $bucket['key_as_string'];
            unset($bucket['key']);
            unset($bucket['key_as_string']);
            unset($bucket['doc_count']);

            //初始化所有坐席的所有统计数据指标为0
            foreach ($items as $item) {
                $parsedResult['data'][$statisticDate][$vccId][$item] = 0;
            }

            /**
             * $bucket为按指标统计的结果，遍历处理各个指标的数据
             */
            foreach ($bucket as $bucketItem => $bucketData) {
                $subBuckets = empty($bucketData['vcc_groups']['buckets']) ?
                    array() : $bucketData['vcc_groups']['buckets'];

                //将可以从搜索结果中获取的指标从“$itemsCanNotGetFromResult”删除
                if (($searchKey = array_search($bucketItem, $itemsCanNotGetFromResult)) !== false) {
                    unset($itemsCanNotGetFromResult[$searchKey]);
                }

                /**
                 * $subBuckets为按企业统计的数据，遍历处理各个企业的统计数据
                 */
                foreach ($subBuckets as $subBucketData) {
                    $vccid = empty($subBucketData['key']) ? 0 : $subBucketData['key'];
                    $docCount = empty($subBucketData['doc_count']) ? 0 : $subBucketData['doc_count'];
                    $parsedResult['data'][$statisticDate][$vccid][$bucketItem] = $docCount;
                    unset($subBucketData['key']);
                    unset($subBucketData['doc_count']);

                    /**
                     * 处理各个指标下的相关指标的统计数据
                     * 例如呼入接通量相关的统计数据为总呼入接通通话时长、平均呼入接通通话时长
                     *
                     * @var string $subBucketDataItem 相关指标
                     * @var array $subBucketDataData 相关指标的值，格式为包含键value的数组或包含子统计的数组
                     */
                    foreach ($subBucketData as $subBucketDataItem => $subBucketDataData) {
                        //将可以从搜索结果中获取的指标从“$itemsCanNotGetFromResult”删除
                        if (($searchKey = array_search($bucketItem, $itemsCanNotGetFromResult)) !== false) {
                            unset($itemsCanNotGetFromResult[$searchKey]);
                        }

                        if (in_array($subBucketDataItem, $items)) {
                            /**
                             * 该项为需要统计的项，不包含子统计的数据
                             */
                            $parsedResult['data'][$statisticDate][$vccid][$subBucketDataItem] =
                                empty($subBucketDataData['value']) ? 0 : $subBucketDataData['value'];
                        } else {
                            /**
                             * 该项为不需要统计的项，判断是否包含子统计数据，包含则继续处理子统计
                             *
                             * 需要统计的项为：示忙原因统计、X秒接通量统计、X秒放弃量统计
                             * 示忙原因统计：根据ext_option使用terms统计每个类别的数量，分类统计的键值根据key字段类命名
                             * X秒接通量统计：根据secs使用range统计各个范围的数量，range统计的各个范围的键值根据to字段来命名
                             * X秒放弃量统计：根据secs使用range统计各个范围的数量，range统计的各个范围的键值根据to字段来命名
                             *
                             * 处理方式为将统计的结果存在在键值为该指标名称的数组下，例如
                             * "inboundConnInXSecsNum": {
                             *   "15": 1356,
                             *   "20": 1384,
                             *   "25": 1419,
                             *   "30": 1441,
                             *   "45": 1484
                             *   },
                             *   "inboundConnInXSecsRate": {
                             *   "15": "85.77%",
                             *   "20": "87.54%",
                             *   "25": "89.75%",
                             *   "30": "91.14%",
                             *   "45": "93.86%"
                             *   }
                             */
                            if (isset($subBucketDataData['buckets'])) {
                                $childBuckets = empty($subBucketDataData['buckets']) ?
                                    array() : $subBucketDataData['buckets'];
                                $parsedResult['data'][$statisticDate][$vccid][$bucketItem] = array();

                                /**
                                 * 继续处理子统计中的项【包括X秒接通量、X秒放弃量、示忙原因统计】
                                 */
                                foreach ($childBuckets as $childBucket) {
                                    if (isset($childBucket['to'])) {
                                        //将15.0001等转为整数15，用于统计range统计，此统计没有相关指标的统计，例如相关的时长
                                        $childKey = !empty($childBucket['to']) || $childBucket['to'] == 0 ?
                                            intval($childBucket['to']) : "0";
                                        $count = empty($childBucket['doc_count']) ? 0 : $childBucket['doc_count'];
                                        $parsedResult['data'][$statisticDate][$vccid][$bucketItem][$childKey] = $count;
                                    } else {
                                        //用于统计子项中的terms统计，例如统计具体示忙原因的ext_option字段的统计
                                        $childKey = !empty($childBucket['key']) || $childBucket['key'] == 0 ?
                                            strval($childBucket['key']) : "0";
                                        $count = empty($childBucket['doc_count']) ? 0 : $childBucket['doc_count'];
                                        $parsedResult['data'][$statisticDate][$vccid][$bucketItem][$childKey] = $count;

                                        unset($childBucket['key']);
                                        unset($childBucket['doc_count']);
                                        /**
                                         * 处理子统计中的相关指标
                                         */
                                        foreach ($childBucket as $cbk => $childBucketData) {
                                            if (!is_array($parsedResult['data'][$statisticDate][$vccid][$cbk])) {
                                                $parsedResult['data'][$statisticDate][$vccid][$cbk] = array();
                                            }
                                            $parsedResult['data'][$statisticDate][$vccid][$cbk][$childKey] =
                                                empty($childBucketData['value']) ? 0 : $childBucketData['value'];
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        //处理需要计算的项
        foreach ($parsedResult['data'] as $dateStatistic => $dateStatisticData) {
            //遍历处理技能组的数据
            foreach ($dateStatisticData as $queStatistic => $queStatisticData) {
                //遍历处理各个指标的数据
                foreach ($queStatisticData as $item => $itemData) {
                    //如果是搜索结果中未统计的项并且是需要计算的项，则执行计算
                    if (in_array($item, $itemsCanNotGetFromResult) && isset($this->calculateItems[$item])) {
                        $calculateRules = empty($this->calculateItems[$item]) ? array() : $this->calculateItems[$item];

                        //未设置计算规则
                        if (empty($calculateRules)) {
                            continue;
                        }

                        $calculItemConfig = isset($calculateItems['system']) ? $calculateItems['system'] : array();
                        $numerator = empty($calculateRules['numerator']) ? array() : $calculateRules['numerator'];
                        $denominator = empty($calculateRules['denominator']) ? array() : $calculateRules['denominator'];
                        $numeratorValue = 0;
                        $denominatorValue = 0;

                        //计算分母的值
                        foreach ($denominator as $ruleItem) {
                            if (is_array($ruleItem)) {
                                foreach ($ruleItem as $key => $rules) {
                                    if ($key == 'multiply') {
                                        if (empty($rules['plus'] && empty($rules['minus']))) {
                                            continue;
                                        }
                                        $denominatorValue += $this->processMultiplyItems($rules, $queStatisticData, $parsedResult['data'][$dateStatistic][$queStatistic], array_keys($calculItemConfig));
                                    } else {
                                        foreach ($rules as $rule) {
                                            if (empty($rule)) {
                                                continue;
                                            }
                                            if (!isset($queStatisticData[$rule])) {
                                                //如果配置项中出现了数字，则为自定义数值的情况，直接用该数字进行运算
                                                if (is_numeric($rule)) {
                                                    $queStatisticData[$rule] = (int) $rule;
                                                    $parsedResult['data'][$dateStatistic][$queStatistic][$rule] = (int) $rule;
                                                } else {
                                                    $queStatisticData[$rule] = '';
                                                }
                                            }
                                            if (is_array($queStatisticData[$rule])) {
                                                foreach ($queStatisticData[$rule] as $val) {
                                                    $denominatorValue += $val;
                                                }
                                            } else {
                                                $calculItems = array();
                                                $calculItemConfig = isset($calculateItems['system']) ? $calculateItems['system'] : array();
                                                foreach ($calculItemConfig as $calculItemK => $calculItemV) {
                                                    $calculItems[] = $calculItemK;
                                                }

                                                if (in_array($rule, $calculItems)) {
                                                    if ($key == 'plus') {
                                                        $denominatorValue += isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                    } else {
                                                        $denominatorValue -= isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                    }
                                                } else {
                                                    if ($key == 'plus') {
                                                        $denominatorValue += $queStatisticData[$rule];
                                                    } else {
                                                        $denominatorValue -= $queStatisticData[$rule];
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            } else {
                                if (is_numeric($ruleItem)) {
                                    $queStatisticData = (int) $ruleItem;
                                }
                                $denominatorValue += $queStatisticData[$ruleItem];
                            }
                        }

                        //计算分子的值
                        foreach ($numerator as $ruleItem) {
                            if (is_array($ruleItem)) {
                                foreach ($ruleItem as $key => $rules) {
                                    if ($key == 'multiply') {
                                        if (empty($rules['plus'] && empty($rules['minus']))) {
                                            continue;
                                        }
                                        $numeratorValue += $this->processMultiplyItems($rules, $queStatisticData, $parsedResult['data'][$dateStatistic][$queStatistic], array_keys($calculItemConfig));
                                    } else {
                                        foreach ($rules as $rule) {
                                            if (!isset($queStatisticData[$rule])) {
                                                if (is_numeric($rule)) {
                                                    $queStatisticData[$rule] = (int) $rule;
                                                    $parsedResult['data'][$dateStatistic][$queStatistic][$rule] = (int) $rule;
                                                } else {
                                                    $queStatisticData[$rule] = '';
                                                }
                                            }
                                            $ruleItemValue = 0;
                                            if (is_array($queStatisticData[$rule])) {
                                                foreach ($queStatisticData[$rule] as $val) {
                                                    $ruleItemValue = isset($queStatisticData[$val]) ? $queStatisticData[$val] : 0;
                                                }
                                            } else {
                                                $ruleItemValue = isset($queStatisticData[$rule]) ? $queStatisticData[$rule] : 0;
                                            }
                                            if (is_array($ruleItemValue)) {
                                                $numeratorValue = array();
                                                //需要计算的值为一个数组，如X秒接通量、接通率
                                                foreach ($ruleItemValue as $key => $value) {
                                                    if (isset($numeratorValue[$key])) {
                                                        $numeratorValue[$key] += isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                                    } else {
                                                        $numeratorValue[$key] = isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                                    }
                                                }
                                            } else {
                                                if (is_array($queStatisticData[$rule])) {
                                                    foreach ($queStatisticData[$rule] as $val) {
                                                        $numeratorValue += $val;
                                                    }
                                                } else {
                                                    $calculItems = array();
                                                    $calculItemConfig = isset($calculateItems['system']) ? $calculateItems['system'] : array();
                                                    foreach ($calculItemConfig as $calculItemK => $calculItemV) {
                                                        $calculItems[] = $calculItemK;
                                                    }
                                                    if (in_array($rule, $calculItems)) {
                                                        if ($key == 'plus') {
                                                            $numeratorValue += isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                        } else {
                                                            $numeratorValue -= isset($parsedResult['data'][$dateStatistic][$queStatistic][$rule]) ? $parsedResult['data'][$dateStatistic][$queStatistic][$rule] : 0;
                                                        }
                                                    } else {
                                                        if ($key == 'plus') {
                                                            $numeratorValue += $queStatisticData[$rule];
                                                        } else {
                                                            $numeratorValue -= $queStatisticData[$rule];
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            } else {
                                $ruleItemValue = isset($queStatisticData[$ruleItem]) ? $queStatisticData[$ruleItem] : is_numeric($ruleItem) ? (int) $ruleItem : 0;
                                if (is_array($ruleItemValue)) {
                                    $numeratorValue = array();
                                    //需要计算的值为一个数组，如X秒接通量、接通率
                                    foreach ($ruleItemValue as $key => $value) {
                                        if (isset($numeratorValue[$key])) {
                                            $numeratorValue[$key] += isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                        } else {
                                            $numeratorValue[$key] = isset($ruleItemValue[$key]) ? $ruleItemValue[$key] : 0;
                                        }
                                    }
                                } else {
                                    //需要计算的值为单个值
                                    if (is_numeric($ruleItem)) {
                                        $queStatisticData[$ruleItem] = (int) $ruleItem;
                                    }
                                    $numeratorValue += $queStatisticData[$ruleItem];
                                }
                            }
                        }

                        //计算统计项的值
                        if (isset($calculateItems['system'][$item])) {
                            if (empty($calculateItems['system'][$item]['percent'])) {
                                if (is_array($numeratorValue)) {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                    foreach ($numeratorValue as $key => $value) {
                                        $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                            $denominatorValue == 0 ?
                                                $numeratorValue[$key] : (round($numeratorValue[$key] / $denominatorValue, 1));
                                    }
                                } else {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                        $numeratorValue : (round($numeratorValue / $denominatorValue, 1));
                                }
                            } else {
                                if (is_array($numeratorValue)) {
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                    foreach ($numeratorValue as $key => $value) {
                                        if ($denominatorValue == 0) {
                                            $resultValue = 0;
                                        } else {
                                            if (($numeratorValue[$key] / $denominatorValue) > 1) {
                                                $resultValue = 1;
                                            } else {
                                                $resultValue = ($numeratorValue[$key] / $denominatorValue);
                                            }
                                        }
                                        $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                            $denominatorValue == 0 ?
                                                '0%' : (round($resultValue, 4) * 100).'%';
                                    }
                                } else {
                                    if ($denominatorValue == 0) {
                                        $resultValue = 0;
                                    } else {
                                        if (($numeratorValue / $denominatorValue) > 1) {
                                            $resultValue = 1;
                                        } else {
                                            $resultValue = ($numeratorValue / $denominatorValue);
                                        }
                                    }
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                        '0%' : (round($resultValue, 4) * 100).'%';
                                }
                            }
                        } else {
                            if (is_array($numeratorValue)) {
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item] = array();
                                foreach ($numeratorValue as $key => $value) {
                                    if ($denominatorValue == 0) {
                                        $resultValue = 0;
                                    } else {
                                        if (($numeratorValue[$key] / $denominatorValue) > 1) {
                                            $resultValue = 1;
                                        } else {
                                            $resultValue = ($numeratorValue[$key] / $denominatorValue);
                                        }
                                    }
                                    $parsedResult['data'][$dateStatistic][$queStatistic][$item][$key] =
                                        $denominatorValue == 0 ?
                                            '0%' : (round($resultValue, 4) * 100).'%';
                                }
                            } else {
                                if ($denominatorValue == 0) {
                                    $resultValue = 0;
                                } else {
                                    if (($numeratorValue / $denominatorValue) > 1) {
                                        $resultValue = 1;
                                    } else {
                                        $resultValue = ($numeratorValue / $denominatorValue);
                                    }
                                }
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item] = $denominatorValue == 0 ?
                                    '0%' : (round($resultValue, 4) * 100).'%';
                            }
                        }
                    }

                    //处理浮点数的格式
                    if (is_float($itemData)) {
                        $parsedResult['data'][$dateStatistic][$queStatistic][$item] = round($itemData, 1);
                    } elseif (is_array($itemData)) {
                        foreach ($itemData as $subItem => $data) {
                            if (is_float($data)) {
                                $parsedResult['data'][$dateStatistic][$queStatistic][$item][$subItem] = round($data, 1);
                            }
                        }
                    }
                }
            }
        }

        return $parsedResult;
    }

    /**
     * 处理乘法运算
     *
     * @param $repItems
     * @param $queStatisticData
     * @param $parsedResult
     * @param $calculateItems
     * @return float|int
     */
    public function processMultiplyItems($repItems, $queStatisticData, $parsedResult, $calculateItems)
    {
        $totalValue = 0;
        if (!empty($repItems['plus'])) {
            $totalValue += $this->dealCalculateForMultiply($repItems['plus'], $queStatisticData, $parsedResult, $calculateItems);
        }

        if (!empty($repItems['minus'])) {
            $totalValue -= $this->dealCalculateForMultiply($repItems['minus'], $queStatisticData, $parsedResult, $calculateItems);
        }

        return $totalValue;
    }

    /**
     * 处理乘法运算中的加减法
     *
     * @param $calculate //加法项或减法项
     * @param $queStatisticData
     * @param $parsedResult
     * @param $calculateItems
     * @return float|int
     */
    protected function dealCalculateForMultiply($calculate, $queStatisticData, $parsedResult, $calculateItems)
    {
        $calculateTotal = 0;
        if (!empty($calculate)) {
            foreach ($calculate as $plusItems)
                $multiplyPlusItmes = explode('*', $plusItems);
            if ($multiplyPlusItmes[0] != 1) {
                if (in_array($multiplyPlusItmes[0], $calculateItems)) {
                    $multiplyPlusItmesFirst = $parsedResult[$multiplyPlusItmes[0]];
                } else {
                    //如果配置项中出现了数字，则为自定义数值的情况，直接用该数字进行运算
                    if (is_numeric($multiplyPlusItmes[0])) {
                        $multiplyPlusItmesFirst = (int) $multiplyPlusItmes[0];
                    } else {
                        $multiplyPlusItmesFirst = $queStatisticData[$multiplyPlusItmes[0]];
                    }
                }

                if (in_array($multiplyPlusItmes[1], $calculateItems)) {
                    $multiplyPlusItmesSecond = $parsedResult[$multiplyPlusItmes[1]];
                } else {
                    if (is_numeric($multiplyPlusItmes[1])) {
                        $multiplyPlusItmesSecond = (int) $multiplyPlusItmes[1];
                    } else {
                        $multiplyPlusItmesSecond = $queStatisticData[$multiplyPlusItmes[1]];
                    }
                }

                if (is_array($multiplyPlusItmesFirst)) {
                    $sum = 0;
                    foreach ($multiplyPlusItmesFirst as $key => $value) {
                        if (strpos($value, '%')) {
                            $value = floatval($value) / 100;
                        }
                        $sum += $value;
                    }
                    $multiplyPlusItmesFirst = $sum;
                } else {
                    if (strpos($multiplyPlusItmesFirst, '%')) {
                        $multiplyPlusItmesFirst = floatval($multiplyPlusItmesFirst) / 100;
                    }
                }

                if (is_array($multiplyPlusItmesSecond)) {
                    $sum = 0;
                    foreach ($multiplyPlusItmesSecond as $key => $value) {
                        if (strpos($value, '%')) {
                            $value = floatval($value) / 100;
                        }
                        $sum += $value;
                    }
                    $multiplyPlusItmesSecond = $sum;
                } else {
                    if (strpos($multiplyPlusItmesSecond, '%')) {
                        $multiplyPlusItmesSecond = floatval($multiplyPlusItmesSecond) / 100;
                    }
                }

                $multiplyPlusValue = $multiplyPlusItmesFirst*$multiplyPlusItmesSecond;
                $calculateTotal += $multiplyPlusValue;
            } else {
                /** 当乘法配置中只有一个配置项且该配置项在第一个位置，才会计算*/
                if (count($calculate) == 1) {
                    if (in_array($multiplyPlusItmes[1], $calculateItems)) {
                        $multiplyPlusItmesSecond = $parsedResult[$multiplyPlusItmes[1]];
                    } else {
                        if (is_numeric($multiplyPlusItmes[1])) {
                            $multiplyPlusItmesSecond = (int) $multiplyPlusItmes[1];
                        } else {
                            $multiplyPlusItmesSecond = $queStatisticData[$multiplyPlusItmes[1]];
                        }
                    }

                    if (is_array($multiplyPlusItmesSecond)) {
                        $sum = 0;
                        foreach ($multiplyPlusItmesSecond as $key => $value) {
                            if (strpos($value, '%')) {
                                $value = floatval($value) / 100;
                            }
                            $sum += $value;
                        }
                        $multiplyPlusItmesSecond = $sum;
                    } else {
                        if (strpos($multiplyPlusItmesSecond, '%')) {
                            $multiplyPlusItmesSecond = floatval($multiplyPlusItmesSecond) / 100;
                        }
                    }

                    $multiplyPlusValue = 1*$multiplyPlusItmesSecond;
                    $calculateTotal += $multiplyPlusValue;
                }
            }
        }

        return $calculateTotal;
    }
}
